home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / p4 / p4-1_2b.lha / p4-1.2b / lib / p4_rm.c < prev    next >
C/C++ Source or Header  |  1993-02-06  |  12KB  |  418 lines

  1. #include "p4.h"
  2. #include "p4_sys.h"
  3.  
  4. /*
  5.   Defining REDIRECT_OUTPUT allows you to redirect output from
  6.   processes as follows.
  7.   Defining OUT_TO_TERM tty allows you to redirect the
  8.   output from various processes to separate windows.
  9.   */
  10.  
  11. #if defined(REDIRECT_OUTPUT)
  12. #if defined(OUT_TO_TERM)
  13. #define P4_OUTFILE "/dev/ttyp4"
  14. #else
  15. #define P4_OUTFILE "/u/rbutler/p4/tests/out"
  16. #endif
  17. #endif
  18.  
  19. static int rm_num;
  20.  
  21. int rm_start(argc, argv)
  22. int *argc;
  23. char **argv;
  24. {
  25.     int bm_fd, bm_port;
  26.     char *s,*bm_host;
  27.     extern char whoami_p4[];
  28.     struct net_initial_handshake hs;
  29.     struct slave_listener_msg lmsg;
  30.     struct bm_rm_msg msg;
  31.     int type, rc, i, numslaves;
  32.     struct p4_global_data *g;
  33.     char outfile[128];
  34.  
  35.     trap_sig_errs();         /* Errors can happen any time */
  36.  
  37.     sprintf(whoami_p4, "rm_%d", getpid());
  38.     p4_dprintfl(20,"remote master starting\n");
  39.  
  40. #if defined(REDIRECT_OUTPUT)
  41.     freopen(P4_OUTFILE, "w", stdout);
  42.     freopen(P4_OUTFILE, "w", stderr);
  43. #endif
  44.  
  45.     if (*argc < 4)
  46.     p4_error("Invalid arguments to remote_master", *argc);
  47.  
  48.     bm_host = argv[1];
  49.     bm_port = atoi(argv[2]);
  50.  
  51.     bm_fd = net_conn_to_listener(bm_host, bm_port, 5);
  52.     if (bm_fd < 0)
  53.     p4_error("rm_start: net_conn_to_listener failed", bm_port);
  54.  
  55.     net_recv(bm_fd, &hs, sizeof(hs));
  56.     hs.pid = (int) htonl(getpid());
  57.     net_send(bm_fd, &hs, sizeof(hs), FALSE);
  58.  
  59. #   ifdef SYSV_IPC
  60.     sysv_num_shmids = 0;
  61.     sysv_shmid[0]  = -1;
  62.     sysv_semid0 = init_sysv_semset(0);
  63. #   endif
  64.  
  65.     /* Get the initialization information from the bm */
  66.  
  67.     rc = net_recv(bm_fd, &msg, sizeof(msg));
  68.     if (rc == PRECV_EOF)
  69.     p4_error("rm_start: got EOF on net_recv", bm_fd);
  70.     type = p4_n_to_i(msg.type);
  71.     if (type != INITIAL_INFO)
  72.     p4_error("rm_start: unknown type, expecting INITIAL_INFO, type=", type);
  73.     if (strcmp(msg.version,p4_version()) != 0)
  74.     {
  75.     p4_dprintf("my version is %s\n",p4_version());
  76.     p4_error("version does not match master \n",0);
  77.     }
  78.  
  79.     if ((s = (char *) rindex(msg.pgm,'/'))  ==  NULL)
  80.     {
  81.     p4_dprintf("my fullpathname is invalid: %s\n",msg.pgm);
  82.     p4_error("fullpathname is invalid \n",0);
  83.     }
  84.     else
  85.     {
  86.     *s = '\0';  /* chg to directory name only */
  87.     chdir(msg.pgm);
  88.     }
  89.  
  90.     globmemsize = p4_n_to_i(msg.memsize);
  91.     logging_flag = p4_n_to_i(msg.logging_flag);
  92.     if (logging_flag)
  93.     ALOG_ENABLE;
  94.     else
  95.     ALOG_DISABLE;
  96.  
  97.     MD_initmem(globmemsize);
  98.     alloc_global();  /* sets p4_global */
  99.     g = p4_global;
  100.     p4_local = alloc_local_rm();
  101.     g->local_communication_only = FALSE;
  102.     g->num_in_proctable = p4_n_to_i(msg.numinproctab);
  103.     numslaves = p4_n_to_i(msg.numslaves);
  104.     rm_num = p4_n_to_i(msg.rm_num);
  105.     debug_level = p4_n_to_i(msg.debug_level);
  106.     strcpy(outfile, msg.outfile);
  107.     strcpy(p4_global->application_id, msg.application_id);
  108.     p4_dprintfl(90, "got numslaves=%d outfile=%s rm_num=%d dbglvl=%d appid=%s\n",
  109.         numslaves, outfile, rm_num, debug_level, msg.application_id);
  110.  
  111.     MD_initenv();
  112.     usc_init();
  113.  
  114.     if (*outfile)
  115.     {
  116.     freopen(outfile, "w", stdout);
  117.     freopen(outfile, "w", stderr);
  118.     }
  119.  
  120.     SIGNAL_P4(LISTENER_ATTN_SIGNAL, handle_connection_interrupt);
  121.     p4_lock(&g->slave_lock);
  122.     create_rm_processes(numslaves, bm_fd);
  123.     if (!p4_am_i_cluster_master())  /* I was forked in create_rm_processes */
  124.     return(0);
  125.  
  126.     /* Grab the whole proc table from the bm */
  127.     p4_dprintfl(90, "receiving proc table\n");
  128.     receive_proc_table(bm_fd);
  129.  
  130.     /* let local slaves use proctable to identify themselves */
  131.     p4_unlock(&g->slave_lock);
  132.  
  133.     sprintf(whoami_p4, "rm_%d_%d", rm_num, getpid());
  134.     p4_local->my_id = p4_get_my_id_from_proc();
  135.  
  136.     p4_global->low_cluster_id = 
  137.     p4_local->my_id - p4_global->proctable[p4_local->my_id].slave_idx;
  138.     p4_global->hi_cluster_id = 
  139.     p4_global->low_cluster_id + p4_global->local_slave_count;
  140.  
  141.     setup_conntab();
  142.  
  143.     if (p4_local->conntab[0].type == CONN_REMOTE_SWITCH)
  144.     {
  145.     p4_local->conntab[0].switch_port = p4_global->proctable[0].switch_port;
  146.     p4_local->conntab[0].port = bm_fd;
  147.     }
  148.     else if (p4_local->conntab[0].type == CONN_REMOTE_NON_EST)
  149.     {
  150.     p4_local->conntab[0].type = CONN_REMOTE_EST;
  151.     p4_local->conntab[0].port = bm_fd;
  152.     p4_local->conntab[0].same_data_rep =
  153.         same_data_representation(p4_local->my_id,0);
  154.     }
  155.     else
  156.     {
  157.     p4_error("rm_start: invalid conn type in conntab ",
  158.          p4_local->conntab[0].type);
  159.     }
  160.  
  161.     sprintf(whoami_p4, "p%d_%d", p4_get_my_id(), getpid());
  162.  
  163.  
  164. #if defined(IPSC860)  ||  defined(CM5)  ||  defined(NCUBE)
  165.     for (i = 1; i < numslaves; i++)
  166.     {
  167. #       if defined(IPSC860)
  168.     csend((long) INITIAL_INFO, &msg, (long) sizeof(struct bm_rm_msg), 
  169.               (long) i, (long) NODE_PID);
  170.     csend((long) INITIAL_INFO, p4_global->proctable, 
  171.               (long) sizeof(p4_global->proctable), (long) i, (long) NODE_PID);
  172. #       endif
  173. #       if defined(CM5)
  174.     CMMD_send_noblock(i, INITIAL_INFO,  &msg,sizeof(struct bm_rm_msg));
  175.     CMMD_send_noblock(i, INITIAL_INFO,  p4_global->proctable, 
  176.                           sizeof(p4_global->proctable));
  177. #       endif
  178. #       if defined(NCUBE)
  179.     nwrite(&msg, sizeof(struct bm_rm_msg), i, INITIAL_INFO, &unused_flag);
  180.     nwrite(p4_global->proctable, sizeof(p4_global->proctable), i, INITIAL_INFO, &unused_flag);
  181. #       endif
  182.     }
  183. #endif
  184.  
  185.     /* 
  186.        sync with local slaves thus insuring that they have the proctable before 
  187.        syncing with bm (this keeps bm and its slaves  from interrupting the local 
  188.        processes too early; then re-sync with local slaves (thus permitting them to 
  189.        interrupt remotes)
  190.     */
  191.     p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  192.     
  193.     msg.type = p4_i_to_n(SYNC_MSG);
  194.     net_send(bm_fd, &msg, sizeof(msg), FALSE);
  195.     msg.type = -1;  /* reset to verify type received next */
  196.     rc = net_recv(bm_fd, &msg, sizeof(msg));
  197.     type = p4_n_to_i(msg.type);
  198.     if (type != SYNC_MSG)
  199.     p4_error("rm_start: unknown type, expecting SYNC_MSG, type=", type);
  200.     
  201.     p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  202.  
  203.     return(0);
  204. }
  205.  
  206.  
  207. P4VOID create_rm_processes(nslaves, bm_fd)
  208. int nslaves;
  209. int bm_fd;
  210. {
  211.     struct p4_global_data *g = p4_global;
  212.     struct listener_data *l;
  213.     int end_1, end_2, slave_pid, listener_pid;
  214.     int slave_idx, listener_port, listener_fd;
  215.     char rm_host[100];
  216.     int i, rm_switch_port, from;
  217.     struct bm_rm_msg bm_msg;
  218.  
  219. #   if !defined(IPSC860)  &&  !defined(CM5)  &&  !defined(NCUBE)
  220.     if (nslaves > P4_MAX_MSG_QUEUES)
  221.     p4_error("create_rm_processes: more slaves than msg queues \n", nslaves);
  222. #   endif
  223.  
  224.     /*
  225.      * Allocate the listener's local data area, since this process will
  226.      * eventually become the listener.
  227.      */
  228.  
  229.     l = listener_info = alloc_listener_info();
  230.  
  231.     net_setup_anon_listener(10, &listener_port, &listener_fd);
  232.  
  233.     p4_dprintfl(70, "created listener on port %d fd %d\n", listener_port,
  234.         listener_fd);
  235.  
  236.     /* Send off the listener info to the bm */
  237.     bm_msg.type = p4_i_to_n(REMOTE_LISTENER_INFO);
  238.     bm_msg.port = p4_i_to_n(listener_port);
  239.     net_send(bm_fd, &bm_msg, sizeof(struct bm_rm_msg), FALSE);
  240.  
  241.     rm_host[0] = '\0';
  242.     get_qualified_hostname(rm_host);
  243.     rm_switch_port = getswport(rm_host);
  244.  
  245.     /* Send my info to the bm */
  246.     bm_msg.type = p4_i_to_n(REMOTE_MASTER_INFO);
  247.     bm_msg.slave_idx = p4_i_to_n(0);
  248.     bm_msg.slave_pid = p4_i_to_n(getpid());
  249.     bm_msg.switch_port = p4_i_to_n(rm_switch_port);
  250.     strcpy(bm_msg.host_name,rm_host);
  251.     strcpy(bm_msg.machine_type,P4_MACHINE_TYPE);
  252.     net_send(bm_fd, &bm_msg, sizeof(struct bm_rm_msg), FALSE);
  253.  
  254.     g->local_slave_count = 0;
  255.  
  256. #   ifdef TCMP
  257.     tcmp_init(NULL,p4_get_my_cluster_id(),shmem_getclunid());
  258. #   endif
  259.  
  260. #   if defined(IPSC860)  ||  defined(CM5)  ||  defined(NCUBE)
  261.     for (slave_idx = 1; slave_idx <= nslaves - 1; slave_idx++)
  262.     {
  263. #       if defined(IPSC860)
  264.     crecv(INITIAL_INFO, &bm_msg, (long) sizeof(struct bm_rm_msg));
  265. #       endif
  266. #       if defined(CM5)
  267.         CMMD_receive(CMMD_ANY_NODE, INITIAL_INFO, (void *) &bm_msg, 
  268.                      sizeof(struct bm_rm_msg));
  269. #       endif
  270. #       if defined(NCUBE)
  271.         from = NCUBE_ANY_NODE;
  272.         type = INITIAL_INFO;
  273.         nread(&bm_msg, sizeof(struct bm_rm_msg), &from,  &type, &unused_flag);
  274. #       endif
  275.     net_send(bm_fd, &bm_msg, sizeof(struct bm_rm_msg), FALSE);
  276.     g->local_slave_count++;
  277.     }
  278. #   else
  279.  
  280.     get_pipe(&end_1, &end_2);
  281.     for (slave_idx = 1; slave_idx <= nslaves - 1; slave_idx++)
  282.     {
  283.     p4_dprintfl(20,"remote master creating local slave %d\n",slave_idx);
  284.             
  285.     slave_pid = fork_p4();
  286.     if (slave_pid)
  287.         p4_dprintfl(10,"remote master created local slave %d\n",slave_idx);
  288.     if (slave_pid == 0)
  289.     {
  290.         /* In the slave process */
  291.  
  292.         sprintf(whoami_p4, "rm_s_%d_%d_%d", rm_num, slave_idx, getpid());
  293.  
  294.         close(listener_fd);
  295.         p4_local = alloc_local_slave();
  296.         p4_local->listener_fd = end_1;
  297.         close(end_2);
  298.  
  299.             SIGNAL_P4(LISTENER_ATTN_SIGNAL, handle_connection_interrupt);
  300.  
  301.  
  302.         /* hang for a valid proctable */
  303.         p4_lock(&g->slave_lock);
  304.         p4_unlock(&g->slave_lock);
  305.  
  306.         p4_local->my_id = p4_get_my_id_from_proc();
  307.         sprintf(whoami_p4, "p%d_%d", p4_get_my_id(), getpid());
  308.         setup_conntab();
  309.         usc_init();
  310.  
  311. #           ifdef TCMP
  312.             tcmp_init(NULL,p4_get_my_cluster_id(),shmem_getclunid());
  313. #           endif
  314.  
  315.         /* 
  316.            sync with local master twice: once to make sure all slaves 
  317.            have got proctable, and second after the master has synced bm
  318.         */
  319.         p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  320.         p4_barrier(&(p4_global->cluster_barrier),p4_num_cluster_ids());
  321.  
  322.         p4_dprintfl(20, "remote process starting\n");
  323.             ALOG_SETUP(p4_local->my_id,ALOG_TRUNCATE);
  324.             ALOG_LOG(p4_local->my_id,BEGIN_USER,0,"");
  325.         return;
  326.     }
  327.  
  328.     /* Send off the slave info to the bm */
  329.     bm_msg.type = p4_i_to_n(REMOTE_SLAVE_INFO);
  330.     bm_msg.slave_idx = p4_i_to_n(slave_idx);
  331.     bm_msg.slave_pid = p4_i_to_n(slave_pid);
  332.     bm_msg.switch_port = p4_i_to_n(rm_switch_port);
  333.     strcpy(bm_msg.machine_type,P4_MACHINE_TYPE);
  334.     net_send(bm_fd, &bm_msg, sizeof(struct bm_rm_msg), FALSE);
  335.  
  336.     g->local_slave_count++;
  337.     }
  338. #endif
  339.  
  340.     /* Send the end message to the bm */
  341.     bm_msg.type = p4_i_to_n(REMOTE_SLAVE_INFO_END);
  342.     net_send(bm_fd, &bm_msg, sizeof(struct bm_rm_msg), FALSE);
  343.  
  344.     /*
  345.      * Done creating slaves. Now fork off the listener .. we've already
  346.      * created the socket and bound a port to it
  347.      */
  348.  
  349. #   if !defined(IPSC860)  &&  !defined(CM5)  &&  !defined(NCUBE)
  350.     g->listener_port = listener_port;
  351.     p4_local->listener_fd = end_1;
  352.     listener_pid = fork_p4();
  353.     if (listener_pid == 0)
  354.     {
  355.     /* Inside listener */
  356.     sprintf(whoami_p4, "rm_l_%d_%d", rm_num, getpid());
  357.     p4_dprintfl(70, "inside listener pid %d\n", getpid());
  358.     p4_local = alloc_local_listener();
  359.     l->listening_fd = listener_fd;
  360.     l->slave_fd = end_2;
  361.     close(end_1);
  362.     listener();
  363.     exit(0);
  364.     }
  365.  
  366.     /* Else we're still in the remote master */
  367.  
  368.     p4_dprintfl(70, "created listener pid %d\n", listener_pid);
  369.     /* We need to close the fds from the listener setup */
  370.     close(listener_fd);
  371.     close(end_2);
  372.     g->listener_pid = listener_pid;
  373. #   endif
  374. }
  375.  
  376.  
  377. P4VOID receive_proc_table(bm_fd)
  378. int bm_fd;
  379. {
  380.     P4BOOL done;
  381.     struct bm_rm_msg msg;
  382.     int type;
  383.     int port, unix_id, slave_idx, group_id;
  384.     int switch_port;
  385.  
  386.     p4_dprintfl(90, "receive_proc_table\n");
  387.     for (done = FALSE; !done;)
  388.     {
  389.     if (net_recv(bm_fd, &msg, sizeof(msg)) == PRECV_EOF)
  390.         p4_error("recv_proc_table: got net_send_eof", bm_fd);
  391.  
  392.     type = p4_n_to_i(msg.type);
  393.     switch (type)
  394.     {
  395.       case PROC_TABLE_ENTRY:
  396.         group_id = p4_n_to_i(msg.group_id);
  397.         port = p4_n_to_i(msg.port);
  398.         unix_id = p4_n_to_i(msg.unix_id);
  399.         slave_idx = p4_n_to_i(msg.slave_idx);
  400.         switch_port = p4_n_to_i(msg.switch_port);
  401.         p4_dprintfl(90, "got entry gid=%d host=%s port=%d unix_id=%d slave_idx=%d switch_port=%d\n",
  402.             group_id,msg.host_name,port,unix_id,slave_idx,switch_port);
  403.         /* remote master loading proctable from big master */
  404.         install_in_proctable(group_id, port, unix_id, msg.host_name,
  405.                  slave_idx, msg.machine_type, switch_port);
  406.         break;
  407.  
  408.       case PROC_TABLE_END:
  409.         done = TRUE;
  410.         break;
  411.  
  412.       default:
  413.         p4_dprintf("receive_proc_table: got invalid message type %d\n", type);
  414.         break;
  415.     }
  416.     }
  417. }
  418.